import React from "react"
import classnames from "classnames"
import PropTypes from "prop-types"

import { h0 } from "../common/fp"
import Header from "./Header.jsx"

import "./DateSelector.css"

function Day(props) {
  const { day, onSelect } = props

  if (!day) {
    return <td className="null"> </td>
  }

  const classes = []

  const now = h0()
  // 判断这一天是否过去
  if (day < now) {
    classes.push("disabled")
  }

  if ([6, 0].includes(new Date(day).getDay())) {
    classes.push("weekend")
  }

  const dateString = now === day ? "今天" : new Date(day).getDate()

  return (
    <td
      className={classnames(classes)}
      onClick={() => {
        onSelect(day)
      }}
    >
      {dateString}
    </td>
  )
}

Day.propTypes = {
  day: PropTypes.number,
  onSelect: PropTypes.func.isRequired,
}

function Week(props) {
  const { days, onSelect } = props
  return (
    <tr className="date-table-days">
      {days.map((day, idx) => {
        return <Day key={idx} day={day} onSelect={onSelect} />
      })}
    </tr>
  )
}

Week.propTypes = {
  days: PropTypes.array.isRequired,
  onSelect: PropTypes.func.isRequired,
}

function Month(props) {
  const { startingTimeInMonth, onSelect } = props

  const startDay = new Date(startingTimeInMonth)
  const currentDay = new Date(startingTimeInMonth)

  let days = [] // 保存这一月每一天的0时0分0秒

  while (currentDay.getMonth() === startDay.getMonth()) {
    days.push(currentDay.getTime())
    // setDate 不用担心溢出，会自动给月份+1
    currentDay.setDate(currentDay.getDate() + 1)
  }

  // 给前面补空白天，因为第一列是周一，第二列是周二。。。。。
  // 比如第一天是周二，那么前边补一个空白
  // 比如第一天是周日，那么前边补六个空白
  days = new Array(startDay.getDay() ? startDay.getDay() - 1 : 6)
    .fill(null)
    .concat(days)

  const lastDay = new Date(days[days.length - 1])
  // 给后面补空白天，
  days = days.concat(
    new Array(lastDay.getDay() ? 7 - lastDay.getDay() : 0).fill(null)
  )
  // 给前后补空白天为了凑齐一行七天，方便循环一行一行的每周
  const weeks = []

  for (let row = 0; row < days.length / 7; ++row) {
    const week = days.slice(row * 7, (row + 1) * 7)
    weeks.push(week)
  }

  return (
    <table className="date-table">
      <thead>
        <tr>
          <td colSpan="7">
            <h5>
              {startDay.getFullYear()}年 {startDay.getMonth() + 1}月
            </h5>
          </td>
        </tr>
      </thead>
      <tbody>
        <tr className="date-table-weeks">
          <th> 周一 </th>
          <th> 周二 </th>
          <th> 周三 </th>
          <th> 周四 </th>
          <th> 周五 </th>
          <th className="weekend"> 周六 </th>
          <th className="weekend"> 周日 </th>
        </tr>
        {weeks.map((week, idx) => {
          return <Week key={idx} days={week} onSelect={onSelect} />
        })}
      </tbody>
    </table>
  )
}

Month.propTypes = {
  startingTimeInMonth: PropTypes.number.isRequired,
  onSelect: PropTypes.func.isRequired,
}

export default function DateSelector(props) {
  const { show, onSelect, onBack } = props

  // 得到当前月的第一天的0时0分0秒
  const now = new Date()
  now.setHours(0)
  now.setMinutes(0)
  now.setSeconds(0)
  now.setMilliseconds(0)
  now.setDate(1)

  const monthSequence = [now.getTime()]
  // setMonth 不用担心溢出，会自动给年份+1
  // 得到当前月的下一月的第一天的0时0分0秒，跨年时年份也会自动+1
  now.setMonth(now.getMonth() + 1)
  monthSequence.push(now.getTime())
  // 得到当前月的下一月的下一月的第一天的0时0分0秒
  now.setMonth(now.getMonth() + 1)
  monthSequence.push(now.getTime())

  return (
    <div
      className={classnames("date-selector", {
        hidden: !show,
      })}
    >
      <Header title="日期选择" onBack={onBack} />
      <div className="date-selector-tables">
        {monthSequence.map((month) => {
          return (
            <Month
              key={month}
              onSelect={onSelect}
              startingTimeInMonth={month}
            />
          )
        })}
      </div>
    </div>
  )
}

DateSelector.propTypes = {
  show: PropTypes.bool.isRequired,
  onSelect: PropTypes.func.isRequired,
  onBack: PropTypes.func.isRequired,
}
